1 00:00:00,580 --> 00:00:01,420 Welcome. 2 00:00:01,420 --> 00:00:05,890 In this lecture, we're going to take a closer look at meta tables and meta methods to make sure you 3 00:00:05,890 --> 00:00:07,120 understand everything. 4 00:00:07,120 --> 00:00:09,040 So let's just jump right into it. 5 00:00:09,040 --> 00:00:11,530 I'm first going to create a class for us. 6 00:00:11,530 --> 00:00:13,660 We're just going to call it bank account. 7 00:00:13,660 --> 00:00:16,330 This is going to be our bank account class. 8 00:00:16,780 --> 00:00:18,340 And what is the bank account need. 9 00:00:18,340 --> 00:00:20,230 Well a bank account needs an owner right. 10 00:00:20,230 --> 00:00:21,760 Who owns the bank account? 11 00:00:21,940 --> 00:00:23,650 The bank account needs a value. 12 00:00:23,650 --> 00:00:25,210 How much money is stored in it. 13 00:00:25,360 --> 00:00:28,030 And then we'll also need a Pin for the bank account. 14 00:00:28,900 --> 00:00:34,300 This table is going to act as our class and our meta table for any future bank account objects. 15 00:00:34,510 --> 00:00:37,150 Now, what are some functions that our bank account needs? 16 00:00:37,180 --> 00:00:42,460 Well, to create a new bank account of course we're going to need a new constructor. 17 00:00:43,510 --> 00:00:48,790 So if we ever want to create a new bank account, we'll have to pass an owner to this function. 18 00:00:48,790 --> 00:00:53,530 However much money we want to start by putting into our bank account, and then the pin to set for our 19 00:00:53,530 --> 00:00:54,400 bank account. 20 00:00:54,580 --> 00:01:01,600 We also need some functions that the bank account can use, such as depositing into our bank account. 21 00:01:04,440 --> 00:01:07,770 It may be a function to withdraw from our bank account. 22 00:01:12,560 --> 00:01:17,930 And with these functions, we can pass the amount we want to deposit as well as the pin required. 23 00:01:18,500 --> 00:01:21,350 And then we can do the same thing for withdrawing as well. 24 00:01:22,330 --> 00:01:27,580 So inside of our constructor, what we could do is we could create a new variable called self, and 25 00:01:27,580 --> 00:01:29,890 it'll be equal to the set Metatable function. 26 00:01:29,890 --> 00:01:35,650 We'll create a new table and attach the bank account as the meta table. 27 00:01:35,680 --> 00:01:41,770 Now in order for us to access the values that we put in here originally, these properties here, as 28 00:01:41,770 --> 00:01:46,420 well as the functions that are a part of the bank account, we have to set a meta method inside of the 29 00:01:46,420 --> 00:01:48,340 bank account the index meta method. 30 00:01:48,340 --> 00:01:52,900 So bank account dot underscore underscore index is equal to the bank account. 31 00:01:52,900 --> 00:01:59,860 That way whenever I let's say index this table here it's going to check to see hey we've got a bank 32 00:01:59,890 --> 00:02:00,910 account meta method. 33 00:02:00,910 --> 00:02:04,330 And let's see if that index belongs to this meta method. 34 00:02:04,330 --> 00:02:09,580 If it does like deposit or the owner or the value or the pin, then it'll be good to go. 35 00:02:10,290 --> 00:02:13,590 So this section we can call here for our meta methods. 36 00:02:15,030 --> 00:02:21,150 Now that we have this done, we can now access things like the value, the owner and the pin for this 37 00:02:21,150 --> 00:02:25,980 new bank account so we can set the owner equal to the owner that is passed to the function. 38 00:02:25,980 --> 00:02:29,400 We can set the value equal to the value passed to this function. 39 00:02:29,490 --> 00:02:33,120 And we can set the pin to the pin that is passed to this function. 40 00:02:33,480 --> 00:02:37,470 Then we just need to return this new table back to where this function was called. 41 00:02:37,470 --> 00:02:40,890 Now we are able to create new bank account objects. 42 00:02:41,130 --> 00:02:44,520 So if I go down here I can create a new account. 43 00:02:44,520 --> 00:02:48,120 I'll just call this account one equal to bank account dot new. 44 00:02:48,390 --> 00:02:50,910 Let's say the owner is Bob. 45 00:02:51,060 --> 00:02:53,520 Bob wants to put $100 into his bank account. 46 00:02:53,520 --> 00:02:55,950 And his pin will be one, two, three, four. 47 00:02:56,760 --> 00:03:01,950 So now we have a new bank account object and we can do another bank account object. 48 00:03:01,980 --> 00:03:03,840 We'll call this account two. 49 00:03:04,390 --> 00:03:10,630 We'll have a bank account new, and we'll have Jim be the owner of this bank account. 50 00:03:11,020 --> 00:03:14,920 He puts in $500 and he has a pin of four, three, two, one. 51 00:03:15,920 --> 00:03:18,980 Now, let's say I wanted to add these bank accounts together. 52 00:03:18,980 --> 00:03:23,300 Let's say remove value from one bank account and put it into the other one. 53 00:03:23,420 --> 00:03:30,440 So for example, in our first bank account, maybe I want to add the value that is inside of Jim's bank 54 00:03:30,470 --> 00:03:31,820 account account two. 55 00:03:32,720 --> 00:03:38,780 How could I add the value of this bank account, which is 500, and put it in this bank account, which 56 00:03:38,780 --> 00:03:44,300 has a value of 600, meaning we would subtract 500 from this bank account, making it zero, and add 57 00:03:44,300 --> 00:03:49,700 500 to this bank account, making it 600 just by using the addition operator. 58 00:03:49,970 --> 00:03:52,910 Well, this is where the add meta method comes into play. 59 00:03:53,030 --> 00:03:55,820 What we could do for our bank account. 60 00:03:55,820 --> 00:04:01,730 We can set the underscore underscore add meta method equal to a new function. 61 00:04:02,750 --> 00:04:07,280 And this add meta method automatically passes two arguments to our function. 62 00:04:07,280 --> 00:04:13,340 One is the first object we're trying to add to, and then the second object is the other object we want 63 00:04:13,340 --> 00:04:14,780 to add to the first object. 64 00:04:14,960 --> 00:04:16,910 So we can call this adding. 65 00:04:18,050 --> 00:04:23,060 Now, the first thing that I want to make sure of is that this thing that I'm trying to add to my table 66 00:04:23,060 --> 00:04:25,850 is also another bank account object. 67 00:04:25,850 --> 00:04:31,640 But how would I be able to differentiate this table from, let's say, other tables that are in my game? 68 00:04:31,760 --> 00:04:36,050 Well, what we could do for the bank account is we could add another property. 69 00:04:36,640 --> 00:04:42,850 And we could call it underscore, underscore type and set it to some unique type for our bank account. 70 00:04:42,850 --> 00:04:46,150 So let's say this is the type of bank account. 71 00:04:46,600 --> 00:04:50,620 This isn't an actual meta method, but we can just assume it is. 72 00:04:50,650 --> 00:04:53,440 And it's going to store the bank account type for us. 73 00:04:53,950 --> 00:04:59,440 So what we could do is we need to first verify that adding is not null. 74 00:04:59,440 --> 00:05:05,470 Because let's say I tried to do this, it would error, but I want to avoid that error. 75 00:05:05,470 --> 00:05:07,630 So we're going to have to make a check for it. 76 00:05:07,780 --> 00:05:11,560 So we can say if not adding. 77 00:05:11,560 --> 00:05:14,290 So if the value of adding is false. 78 00:05:14,710 --> 00:05:18,760 Or we could check if the type of adding. 79 00:05:19,930 --> 00:05:22,330 Is not equal to the type of table. 80 00:05:23,970 --> 00:05:33,090 And what we could do is we could raise an error and we could say, attempt to add type and we'll concatenate 81 00:05:33,090 --> 00:05:35,280 it with the type of this adding. 82 00:05:36,290 --> 00:05:39,740 And we'll say attempt to add this type to type. 83 00:05:40,640 --> 00:05:46,610 And then we can do self dot underscore underscore type which will reference the type right here. 84 00:05:46,610 --> 00:05:48,980 That is part of the bank account class. 85 00:05:48,980 --> 00:05:53,240 So it'll so if this um so let's say adding was nil. 86 00:05:53,240 --> 00:05:58,670 If it was nil then this would print attempt to add type nil to type bank account. 87 00:05:59,470 --> 00:06:04,930 The next thing we can check for is whether or not the type of this table is a bank account. 88 00:06:04,930 --> 00:06:12,220 So if the adding dot underscore underscore type is not equal to bank account. 89 00:06:14,170 --> 00:06:22,030 Then we can return self and end, and we'll actually need to do that right here as well. 90 00:06:24,870 --> 00:06:30,210 Now we have to make sure we return self, because when we call this addition operator, it's attempting 91 00:06:30,240 --> 00:06:34,830 to create or store a new variable on our account, one which is going to be different from the original. 92 00:06:34,830 --> 00:06:39,960 And we need so we have to return self back to where this function was called. 93 00:06:39,960 --> 00:06:45,390 Otherwise it's not going to work and we won't be able to add any amount to our table. 94 00:06:45,390 --> 00:06:52,440 But once we verify that, what we're trying to add to this table is a table and it is a bank account. 95 00:06:52,620 --> 00:06:54,270 What we could do now. 96 00:06:55,520 --> 00:07:01,130 Is we could use the deposit and withdrawal functions to our advantage. 97 00:07:01,130 --> 00:07:09,980 So for the adding bank account, what we could do is we could withdraw, um, the amount that is inside 98 00:07:09,980 --> 00:07:10,910 of this table. 99 00:07:10,910 --> 00:07:12,590 So adding dot value. 100 00:07:13,100 --> 00:07:17,750 And we'll also make sure to pass the pin to verify, you know, this is the bank account's owner or 101 00:07:17,750 --> 00:07:18,380 whatever. 102 00:07:18,950 --> 00:07:26,030 We could withdraw it from that, and then we could deposit it into the original table using self deposit. 103 00:07:27,250 --> 00:07:31,960 But then the issue here is, how are we going to know the exact amount of adding value? 104 00:07:31,960 --> 00:07:35,020 Because when we withdraw it, it's going to subtract from it. 105 00:07:35,020 --> 00:07:39,790 And we need to set that amount in the deposit well inside of these functions. 106 00:07:40,760 --> 00:07:48,200 What we could do is we could first check if the pin passed to this function is not equal to the pin 107 00:07:48,200 --> 00:07:53,360 of the bank account, then we're just going to return false, meaning the deposit failed. 108 00:07:53,750 --> 00:07:59,570 And then I'm going to return a number which signifies how much money was deposited or withdrawn. 109 00:07:59,570 --> 00:08:01,940 In this case it would be zero because we failed. 110 00:08:02,570 --> 00:08:08,090 We could also check if the amount that they're attempting to deposit into the account is negative for 111 00:08:08,090 --> 00:08:08,750 some reason. 112 00:08:08,750 --> 00:08:12,980 So if the amount is less than or let's say it's equal to zero. 113 00:08:12,980 --> 00:08:19,490 So if it's zero or less, then we're also going to return false and zero and end. 114 00:08:20,450 --> 00:08:27,050 Otherwise if all checks out then we can set self dot value plus equal the amount. 115 00:08:27,600 --> 00:08:29,190 And then we can return true. 116 00:08:29,220 --> 00:08:35,340 We successfully added this amount and returned the amount we added or deposited into the bank account. 117 00:08:36,010 --> 00:08:40,360 And again, remember we have access to self here is because we're using a cone. 118 00:08:40,360 --> 00:08:45,670 So whenever we call this function directly on a bank account table, the table automatically gets passed 119 00:08:45,670 --> 00:08:47,290 to this function as self. 120 00:08:48,140 --> 00:08:52,580 And then we can basically just copy this and do the same thing here. 121 00:08:52,970 --> 00:08:54,920 But instead what we're going to do. 122 00:08:55,580 --> 00:09:02,330 Is we're going to make a variable, I'll call it amount can withdraw and it's going to be equal to math 123 00:09:02,330 --> 00:09:03,350 dot min. 124 00:09:03,650 --> 00:09:06,920 And we'll pass self dot value and the amount. 125 00:09:07,160 --> 00:09:09,320 So let's say for some reason. 126 00:09:10,300 --> 00:09:14,530 The amount we were trying to withdraw is greater than the amount of money that we already have in the 127 00:09:14,530 --> 00:09:15,190 bank account. 128 00:09:15,190 --> 00:09:19,270 So let's say this was 50 and we only had $10 in our bank account. 129 00:09:19,270 --> 00:09:24,790 Well, this function is going to return to us the smallest number out of the list of numbers we give 130 00:09:24,790 --> 00:09:29,470 to it, which in this case would be $10, because that's all we can withdraw. 131 00:09:29,470 --> 00:09:32,050 And we want to be able to withdraw $50. 132 00:09:32,320 --> 00:09:39,940 So once we get that correct number then we can set self dot value minus equal amount can withdraw and 133 00:09:39,940 --> 00:09:44,320 we return true and we return the amount that we withdrew. 134 00:09:45,750 --> 00:09:46,260 Great. 135 00:09:46,260 --> 00:09:48,360 So now we can go back here. 136 00:09:48,360 --> 00:09:52,830 And what we could do is we could store the result from this function into two variables. 137 00:09:53,830 --> 00:09:58,720 Um, I'm not going to need the first one, but I will need the second one, which will be the amount 138 00:09:58,720 --> 00:10:00,880 that we withdrew out of this account. 139 00:10:01,180 --> 00:10:06,310 And then we can deposit this amount into the original table. 140 00:10:07,180 --> 00:10:10,120 And pass the pen for this table as well. 141 00:10:10,690 --> 00:10:16,270 And then last but not least, we have to make sure to return self at the very end. 142 00:10:17,170 --> 00:10:24,610 So what we've done now is that whenever we attempt to add two bank accounts together, just like this. 143 00:10:25,420 --> 00:10:27,970 It's going to call this ad meta method. 144 00:10:27,970 --> 00:10:32,680 It's going to pass the first table, which is account one, and pass the second table which is account 145 00:10:32,680 --> 00:10:33,190 two. 146 00:10:33,220 --> 00:10:39,160 It's going to make sure that the second table is a table and that it's a type of bank account. 147 00:10:39,160 --> 00:10:45,190 When it is then we're going to withdraw however much money we can out of the second bank account. 148 00:10:45,790 --> 00:10:50,500 And we're going to take that amount and deposit within the original bank account. 149 00:10:50,890 --> 00:10:52,180 That's all we're doing here. 150 00:10:52,180 --> 00:10:57,730 So that means after I add the amount of money that is in account two, to account one, this should 151 00:10:57,730 --> 00:11:01,420 be $600 and our account two should be $0. 152 00:11:01,420 --> 00:11:02,320 So let's find out. 153 00:11:02,320 --> 00:11:05,620 Let's print account one dot value. 154 00:11:05,680 --> 00:11:09,310 And then we can also print account two dot value. 155 00:11:09,310 --> 00:11:14,110 And then we can go and run our game and see what gets printed in the console. 156 00:11:15,240 --> 00:11:15,960 And there we go. 157 00:11:15,960 --> 00:11:22,260 Just like that, we got $600 in our first bank account, and now we have zero in the second bank account. 158 00:11:23,740 --> 00:11:24,730 Pretty neat. 159 00:11:24,730 --> 00:11:29,680 Well, let's say I wanted to subtract the bank accounts. 160 00:11:29,680 --> 00:11:34,810 So let's say I wanted to subtract money, however much I could out of this bank account and put it into 161 00:11:34,810 --> 00:11:36,040 the second bank account. 162 00:11:37,140 --> 00:11:40,140 Well, we have another meta method for that. 163 00:11:40,140 --> 00:11:42,180 And that meta method is called. 164 00:11:42,840 --> 00:11:46,650 Underscore underscore sub short for subtraction. 165 00:11:47,190 --> 00:11:49,230 And again we'll need a function for this. 166 00:11:49,230 --> 00:11:53,040 And it passes the first table we want to subtract from. 167 00:11:53,490 --> 00:11:56,430 And then it also passes us the second table. 168 00:11:56,430 --> 00:11:59,970 We'll call it removing which we want to take out of this. 169 00:11:59,970 --> 00:12:02,910 And I guess we could put it into this bank account. 170 00:12:03,630 --> 00:12:07,470 So what we could do is we could copy the same thing here. 171 00:12:07,530 --> 00:12:08,190 Right. 172 00:12:08,190 --> 00:12:15,270 We want to make sure that the second thing we're trying to subtract from the original table is a table, 173 00:12:15,270 --> 00:12:16,590 and that it's a bank account. 174 00:12:16,590 --> 00:12:20,010 So I'm going to replace these references. 175 00:12:20,400 --> 00:12:27,630 And then what I need to do is I need to call the withdraw function on self. 176 00:12:28,680 --> 00:12:32,880 And I need to withdraw however much money I can. 177 00:12:32,880 --> 00:12:43,110 In this case, I want to withdraw the removing dot value and then we'll make sure to pass self dot pin. 178 00:12:43,260 --> 00:12:48,210 Now we need to store whether or not this withdraw was successful or not. 179 00:12:48,210 --> 00:12:49,950 So success. 180 00:12:49,950 --> 00:12:51,330 And then the amount. 181 00:12:52,190 --> 00:12:54,770 Because let's say the second table had $500. 182 00:12:54,770 --> 00:12:58,730 I wanted to subtract from a table that only had $100. 183 00:12:58,730 --> 00:13:02,120 That means I withdraw would fail, right? 184 00:13:02,210 --> 00:13:04,430 In the case that our withdrawal fails. 185 00:13:04,430 --> 00:13:06,500 So if not successful. 186 00:13:07,300 --> 00:13:14,770 What we could do is the same thing set success amount equal to self withdraw and instead we'll just 187 00:13:14,770 --> 00:13:18,100 withdraw whatever money we have within this bank account. 188 00:13:18,100 --> 00:13:20,590 So dot value. 189 00:13:21,010 --> 00:13:26,860 So we are withdrawing all the money that we can out of self make sure to pass the pin. 190 00:13:28,910 --> 00:13:37,070 And once that's done, then we can go ahead and deposit that money into the second table or the removing 191 00:13:37,100 --> 00:13:37,610 table. 192 00:13:37,610 --> 00:13:38,900 So deposit. 193 00:13:40,270 --> 00:13:43,690 This amount and pass the pin as well. 194 00:13:44,050 --> 00:13:51,220 Otherwise, if we were successful in withdrawing the money, then we can just do the exact same thing 195 00:13:51,220 --> 00:13:52,060 here as well. 196 00:13:52,510 --> 00:13:57,430 And actually, there's a better way to format our code where we don't have to have these two same lines 197 00:13:57,430 --> 00:13:58,870 doing the exact same thing. 198 00:13:58,870 --> 00:14:02,410 What we could do is we could just have one of those lines. 199 00:14:02,410 --> 00:14:08,260 So this if statement will just check if we weren't successful, if we were not successful, then it 200 00:14:08,260 --> 00:14:09,700 updates these variables. 201 00:14:09,700 --> 00:14:15,460 And then once the variable gets updated, then we deposit the correct amount into that second table. 202 00:14:15,460 --> 00:14:22,240 So that means because I changed this to subtraction, what's going to happen is it's going to take the 203 00:14:22,240 --> 00:14:26,800 $100 from this account and put it into our second account. 204 00:14:26,800 --> 00:14:31,330 So the first account should be zero and the second account should be 600. 205 00:14:31,330 --> 00:14:32,260 It should flip. 206 00:14:32,260 --> 00:14:33,760 So let's run and find out. 207 00:14:35,300 --> 00:14:38,540 And we get an error attempt to index nil with value. 208 00:14:39,250 --> 00:14:41,830 Oh, and the reason it did that? 209 00:14:41,830 --> 00:14:42,400 Ha ha! 210 00:14:42,400 --> 00:14:48,670 We have to make sure to return self at the end here, because if we don't return self, it's not going 211 00:14:48,670 --> 00:14:53,230 to know what to update account one with and it's just going to set it to nil. 212 00:14:53,230 --> 00:14:55,600 So this is why we have to return self here. 213 00:14:55,600 --> 00:14:57,580 Otherwise it's going to end up as nil. 214 00:14:58,900 --> 00:15:00,070 So we got that fixed. 215 00:15:00,070 --> 00:15:02,650 We're going to save that and let's run it again. 216 00:15:02,920 --> 00:15:05,920 Should be there we go zero 600. 217 00:15:06,010 --> 00:15:11,860 So we've subtracted however much money we could out of the first account and placed it into the second 218 00:15:11,860 --> 00:15:12,490 account. 219 00:15:13,030 --> 00:15:20,440 Now, if I updated the money in the second account to only be $50, then what should happen is that 220 00:15:20,440 --> 00:15:25,030 it should subtract $50 from the first account and make this account $100. 221 00:15:25,030 --> 00:15:26,200 So let's run it. 222 00:15:26,830 --> 00:15:31,420 And there we go, $50 in the first account, $100 in the second account. 223 00:15:32,690 --> 00:15:38,600 So as you can see, this is how we can use tables and meta tables to imitate classes in Lua. 224 00:15:38,840 --> 00:15:44,330 We can also take all this functionality and store it in a different script, which would be our module 225 00:15:44,330 --> 00:15:44,780 script. 226 00:15:44,780 --> 00:15:46,820 So let's actually do that real quick. 227 00:15:46,850 --> 00:15:52,400 I'm going to go into server storage, and I actually already have a folder in here called classes. 228 00:15:52,400 --> 00:15:55,790 And what I'm going to do is I'm going to create a new module script in here. 229 00:15:56,030 --> 00:15:59,990 And this is going to be my bank account class. 230 00:16:01,530 --> 00:16:07,530 And because a module script returns a table, we can literally just use the table that we declared right 231 00:16:07,530 --> 00:16:11,310 here as the table to return in this module script. 232 00:16:11,580 --> 00:16:14,880 So actually let's go and copy all of this functionality. 233 00:16:15,480 --> 00:16:17,070 And we can delete this. 234 00:16:17,070 --> 00:16:22,110 And at the very end of our module script we can just return the bank account table. 235 00:16:22,650 --> 00:16:31,380 So now whenever we require this module script from a script in our server, we can get this bank account 236 00:16:31,380 --> 00:16:32,010 class. 237 00:16:32,010 --> 00:16:37,440 And then we can use the bank account new function to create new bank account objects. 238 00:16:37,440 --> 00:16:41,160 And we can use the same deposit and withdrawal functions. 239 00:16:41,160 --> 00:16:47,490 And we can use the same subtraction and addition meta methods that are inside of our bank account class. 240 00:16:47,880 --> 00:16:54,210 So this is kind of the core essential idea of meta methods and meta tables as classes in Lua. 241 00:16:55,200 --> 00:17:00,060 In the next lectures, we're going to go ahead and move forward into some other territory in object 242 00:17:00,060 --> 00:17:07,290 oriented programming such as inheritance, polymorphism, abstraction, and a bunch of other neat stuff. 243 00:17:07,290 --> 00:17:08,880 So I hope to see you there.